<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

  
  <title>【Activiti7】1、SpringBoot整合Activiti7 | 亦人亦码</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="Activiti7发布正式版之后，它与SpringBoot2.x已经完全支持整合开发。">
<meta property="og:type" content="article">
<meta property="og:title" content="【Activiti7】1、SpringBoot整合Activiti7">
<meta property="og:url" content="https://xlh_blog.gitee.io/2023/04/04/%E3%80%90Activiti7%E3%80%911%E3%80%81SpringBoot%E6%95%B4%E5%90%88Activiti7/index.html">
<meta property="og:site_name" content="亦人亦码">
<meta property="og:description" content="Activiti7发布正式版之后，它与SpringBoot2.x已经完全支持整合开发。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://xlh_blog.gitee.io/2023/04/04/%E3%80%90Activiti7%E3%80%911%E3%80%81SpringBoot%E6%95%B4%E5%90%88Activiti7/bb6d77584b43f67fa97a7c4d09dce686.png">
<meta property="article:published_time" content="2023-04-04T08:31:38.000Z">
<meta property="article:modified_time" content="2023-04-06T07:44:34.543Z">
<meta property="article:author" content="Mr.xi">
<meta property="article:tag" content="Java, PHP,Linux,博客">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://xlh_blog.gitee.io/2023/04/04/%E3%80%90Activiti7%E3%80%911%E3%80%81SpringBoot%E6%95%B4%E5%90%88Activiti7/bb6d77584b43f67fa97a7c4d09dce686.png">
  
    <link rel="alternate" href="/atom.xml" title="亦人亦码" type="application/atom+xml">
  
  
    <link rel="icon" href="/image/favicon.png">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  
<link rel="stylesheet" href="/css/style.css">


<meta name="generator" content="Hexo 5.4.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">亦人亦码</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
          <a class="main-nav-link" href="/about">About</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="搜索"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="https://xlh_blog.gitee.io"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main"><article id="post-【Activiti7】1、SpringBoot整合Activiti7" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2023/04/04/%E3%80%90Activiti7%E3%80%911%E3%80%81SpringBoot%E6%95%B4%E5%90%88Activiti7/" class="article-date">
  <time datetime="2023-04-04T08:31:38.000Z" itemprop="datePublished">2023-04-04</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/Activiti7/">Activiti7</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      【Activiti7】1、SpringBoot整合Activiti7
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>Activiti7发布正式版之后，它与SpringBoot2.x已经完全支持整合开发。</p>
<span id="more"></span>

<h2 id="1-1-SpringBoot整合Activiti7的配置"><a href="#1-1-SpringBoot整合Activiti7的配置" class="headerlink" title="1.1 SpringBoot整合Activiti7的配置"></a>1.1 SpringBoot整合Activiti7的配置</h2><p>为了能够实现SpringBoot与Activiti7整合开发，首先我们要引入相关的依赖支持。</p>
<p>在工程的pom.xml文件中引入相关的依赖，其中activiti的依赖是：activiti-spring-boot-starter。</p>
<p>具体依赖如下所示：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">parent</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.1.0.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">parent</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">properties</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">project.build.sourceEncoding</span>&gt;</span>UTF-8<span class="tag">&lt;/<span class="name">project.build.sourceEncoding</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">project.reporting.outputEncoding</span>&gt;</span>UTF-8<span class="tag">&lt;/<span class="name">project.reporting.outputEncoding</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">java.version</span>&gt;</span>1.8<span class="tag">&lt;/<span class="name">java.version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">properties</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-web<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-jdbc<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-test<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.activiti<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>activiti-spring-boot-starter<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>7.0.0.Beta2<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>mysql<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>mysql-connector-java<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>5.1.29<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.projectlombok<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>lombok<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">build</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">plugins</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">plugin</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-maven-plugin<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">plugin</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">plugins</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">build</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>通过该pom.xml文件所导入的坐标，我们就可以实现activiti7与Springboot整合。</p>
<h2 id="1-2-SpringBoot的application-yml文件配置"><a href="#1-2-SpringBoot的application-yml文件配置" class="headerlink" title="1.2 SpringBoot的application.yml文件配置"></a>1.2 SpringBoot的application.yml文件配置</h2><p>为了能够实现Activiti7生成的表放到Mysql数据库中，需要在配置文件application.yml中添加相关的配置</p>
<p>注意：activiti7默认没有开启数据库历史记录，需要手动配置开启</p>
<figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">spring</span>:<span class="string"></span></span><br><span class="line">  <span class="attr">datasource</span>:<span class="string"></span></span><br><span class="line">    <span class="attr">url</span>: <span class="string">jdbc:mysql:///activiti?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=GMT</span></span><br><span class="line">    <span class="attr">username</span>: <span class="string">root</span></span><br><span class="line">    <span class="attr">password</span>: <span class="string">123456</span></span><br><span class="line">    <span class="meta">driver-class-name</span>: <span class="string">com.mysql.jdbc.Driver</span></span><br><span class="line">  <span class="attr">activiti</span>:<span class="string"></span></span><br><span class="line"><span class="comment">    #1.flase：默认值。activiti在启动时，对比数据库表中保存的版本，如果没有表或者版本不匹配，将抛出异常</span></span><br><span class="line"><span class="comment">    #2.true： activiti会对数据库中所有表进行更新操作。如果表不存在，则自动创建</span></span><br><span class="line"><span class="comment">    #3.create_drop： 在activiti启动时创建表，在关闭时删除表（必须手动关闭引擎，才能删除表）</span></span><br><span class="line"><span class="comment">    #4.drop-create： 在activiti启动时删除原来的旧表，然后在创建新表（不需要手动关闭引擎）</span></span><br><span class="line">    <span class="meta">database-schema-update</span>: <span class="string">true</span></span><br><span class="line"><span class="comment">    #检测历史表是否存在 activiti7默认没有开启数据库历史记录 启动数据库历史记录</span></span><br><span class="line">    <span class="meta">db-history-used</span>: <span class="string">true</span></span><br><span class="line"><span class="comment">    #记录历史等级 可配置的历史级别有none, activity, audit, full</span></span><br><span class="line"><span class="comment">    #none：不保存任何的历史数据，因此，在流程执行过程中，这是最高效的。</span></span><br><span class="line"><span class="comment">    #activity：级别高于none，保存流程实例与流程行为，其他数据不保存。</span></span><br><span class="line"><span class="comment">    #audit：除activity级别会保存的数据外，还会保存全部的流程任务及其属性。audit为history的默认值。</span></span><br><span class="line"><span class="comment">    #full：保存历史数据的最高级别，除了会保存audit级别的数据外，还会保存其他全部流程相关的细节数据，包括一些流程参数等。</span></span><br><span class="line">    <span class="meta">history-level</span>: <span class="string">full</span></span><br><span class="line"><span class="comment">    #校验流程文件，默认校验resources下的processes文件夹里的流程文件</span></span><br><span class="line">    <span class="meta">check-process-definitions</span>: <span class="string">false</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="1-3-编写启动类"><a href="#1-3-编写启动类" class="headerlink" title="1.3 编写启动类"></a>1.3 编写启动类</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima;</span><br><span class="line">​</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.SpringApplication;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.autoconfigure.SpringBootApplication;</span><br><span class="line">​</span><br><span class="line"><span class="meta">@SpringBootApplication</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ActApplication</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        SpringApplication.run(ActApplication.class,args);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="1-4-添加SpringSecurity安全框架整合配置"><a href="#1-4-添加SpringSecurity安全框架整合配置" class="headerlink" title="1.4 添加SpringSecurity安全框架整合配置"></a>1.4 添加SpringSecurity安全框架整合配置</h2><p>因为Activiti7与SpringBoot整合后，默认情况下，集成了SpringSecurity安全框架，这样我们就要去准备SpringSecurity整合进来的相关用户权限配置信息。</p>
<p>SpringBoot的依赖包已经将SpringSecurity的依赖包也添加进项目中。</p>
<h3 id="1-4-1-添加SecurityUtil类"><a href="#1-4-1-添加SecurityUtil类" class="headerlink" title="1.4.1 添加SecurityUtil类"></a>1.4.1 添加SecurityUtil类</h3><p>为了能够快速实现SpringSecurity安全框架的配置，所添加的一个组件。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.utils;</span><br><span class="line">​</span><br><span class="line"><span class="keyword">import</span> org.slf4j.Logger;</span><br><span class="line"><span class="keyword">import</span> org.slf4j.LoggerFactory;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.annotation.Qualifier;</span><br><span class="line"><span class="keyword">import</span> org.springframework.security.core.Authentication;</span><br><span class="line"><span class="keyword">import</span> org.springframework.security.core.GrantedAuthority;</span><br><span class="line"><span class="keyword">import</span> org.springframework.security.core.context.SecurityContextHolder;</span><br><span class="line"><span class="keyword">import</span> org.springframework.security.core.context.SecurityContextImpl;</span><br><span class="line"><span class="keyword">import</span> org.springframework.security.core.userdetails.UserDetails;</span><br><span class="line"><span class="keyword">import</span> org.springframework.security.core.userdetails.UserDetailsService;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Component;</span><br><span class="line">​</span><br><span class="line"><span class="keyword">import</span> java.util.Collection;</span><br><span class="line">​</span><br><span class="line">​</span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SecurityUtil</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> Logger logger = LoggerFactory.getLogger(SecurityUtil.class);</span><br><span class="line">​</span><br><span class="line">     <span class="meta">@Autowired</span></span><br><span class="line">     <span class="meta">@Qualifier(&quot;myUserDetailsService&quot;)</span></span><br><span class="line">     <span class="keyword">private</span> UserDetailsService userDetailsService;</span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">logInAs</span><span class="params">(String username)</span> </span>&#123;</span><br><span class="line">     UserDetails user = userDetailsService.loadUserByUsername(username);</span><br><span class="line">​</span><br><span class="line">     <span class="keyword">if</span> (user == <span class="keyword">null</span>) &#123;</span><br><span class="line">         <span class="keyword">throw</span> <span class="keyword">new</span> IllegalStateException(<span class="string">&quot;User &quot;</span> + username + <span class="string">&quot; doesn&#x27;t exist, please provide a valid user&quot;</span>);</span><br><span class="line">     &#125;</span><br><span class="line">     logger.info(<span class="string">&quot;&gt; Logged in as: &quot;</span> + username);</span><br><span class="line">​</span><br><span class="line">     SecurityContextHolder.setContext(</span><br><span class="line">             <span class="keyword">new</span> SecurityContextImpl(</span><br><span class="line">                     <span class="keyword">new</span> Authentication() &#123;</span><br><span class="line">                         <span class="meta">@Override</span></span><br><span class="line">                         <span class="keyword">public</span> Collection&lt;? extends GrantedAuthority&gt; getAuthorities() &#123;</span><br><span class="line">                             <span class="keyword">return</span> user.getAuthorities();</span><br><span class="line">                         &#125;</span><br><span class="line">                         <span class="meta">@Override</span></span><br><span class="line">                         <span class="function"><span class="keyword">public</span> Object <span class="title">getCredentials</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                             <span class="keyword">return</span> user.getPassword();</span><br><span class="line">                         &#125;</span><br><span class="line">                         <span class="meta">@Override</span></span><br><span class="line">                         <span class="function"><span class="keyword">public</span> Object <span class="title">getDetails</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                             <span class="keyword">return</span> user;</span><br><span class="line">                         &#125;</span><br><span class="line">                         <span class="meta">@Override</span></span><br><span class="line">                         <span class="function"><span class="keyword">public</span> Object <span class="title">getPrincipal</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                             <span class="keyword">return</span> user;</span><br><span class="line">                         &#125;</span><br><span class="line">                         <span class="meta">@Override</span></span><br><span class="line">                         <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isAuthenticated</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                             <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">                         &#125;</span><br><span class="line">                         <span class="meta">@Override</span></span><br><span class="line">                         <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setAuthenticated</span><span class="params">(<span class="keyword">boolean</span> isAuthenticated)</span> <span class="keyword">throws</span> IllegalArgumentException </span>&#123; &#125;</span><br><span class="line">                         <span class="meta">@Override</span></span><br><span class="line">                         <span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                             <span class="keyword">return</span> user.getUsername();</span><br><span class="line">                         &#125;</span><br><span class="line">     &#125;));</span><br><span class="line">     org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);</span><br><span class="line"> &#125;</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure>

<p>这个类可以从我们下载的Activiti7官方提供的Example中找到。</p>
<h3 id="1-4-2-添加DemoApplicationConfig类"><a href="#1-4-2-添加DemoApplicationConfig类" class="headerlink" title="1.4.2 添加DemoApplicationConfig类"></a>1.4.2 添加DemoApplicationConfig类</h3><p>在Activiti7官方下载的Example中找到DemoApplicationConfig类，它的作用是为了实现SpringSecurity框架的用户权限的配置，这样我们就可以在系统中使用用户权限信息。</p>
<p>本次项目中基本是在文件中定义出来的用户信息，当然也可以是数据库中查询的用户权限信息。</p>
<p>后面处理流程时用到的任务负责人，需要添加在这里</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.config;</span><br><span class="line">​</span><br><span class="line"><span class="keyword">import</span> org.slf4j.Logger;</span><br><span class="line"><span class="keyword">import</span> org.slf4j.LoggerFactory;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Bean;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Configuration;</span><br><span class="line"><span class="keyword">import</span> org.springframework.security.core.authority.SimpleGrantedAuthority;</span><br><span class="line"><span class="keyword">import</span> org.springframework.security.core.userdetails.User;</span><br><span class="line"><span class="keyword">import</span> org.springframework.security.core.userdetails.UserDetailsService;</span><br><span class="line"><span class="keyword">import</span> org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;</span><br><span class="line"><span class="keyword">import</span> org.springframework.security.crypto.password.PasswordEncoder;</span><br><span class="line"><span class="keyword">import</span> org.springframework.security.provisioning.InMemoryUserDetailsManager;</span><br><span class="line">​</span><br><span class="line"><span class="keyword">import</span> java.util.Arrays;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"><span class="keyword">import</span> java.util.stream.Collectors;</span><br><span class="line">​</span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">DemoApplicationConfiguration</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> Logger logger = LoggerFactory.getLogger(DemoApplicationConfiguration.class);</span><br><span class="line">     <span class="meta">@Bean</span></span><br><span class="line">     <span class="function"><span class="keyword">public</span> UserDetailsService <span class="title">myUserDetailsService</span><span class="params">()</span> </span>&#123;</span><br><span class="line">         InMemoryUserDetailsManager inMemoryUserDetailsManager = <span class="keyword">new</span> InMemoryUserDetailsManager();</span><br><span class="line">         <span class="comment">//这里添加用户，后面处理流程时用到的任务负责人，需要添加在这里</span></span><br><span class="line">         String[][] usersGroupsAndRoles = &#123;</span><br><span class="line">                 &#123;<span class="string">&quot;jack&quot;</span>, <span class="string">&quot;password&quot;</span>, <span class="string">&quot;ROLE_ACTIVITI_USER&quot;</span>, <span class="string">&quot;GROUP_activitiTeam&quot;</span>&#125;,</span><br><span class="line">                 &#123;<span class="string">&quot;rose&quot;</span>, <span class="string">&quot;password&quot;</span>, <span class="string">&quot;ROLE_ACTIVITI_USER&quot;</span>, <span class="string">&quot;GROUP_activitiTeam&quot;</span>&#125;,</span><br><span class="line">                 &#123;<span class="string">&quot;tom&quot;</span>, <span class="string">&quot;password&quot;</span>, <span class="string">&quot;ROLE_ACTIVITI_USER&quot;</span>, <span class="string">&quot;GROUP_activitiTeam&quot;</span>&#125;,</span><br><span class="line">                 &#123;<span class="string">&quot;other&quot;</span>, <span class="string">&quot;password&quot;</span>, <span class="string">&quot;ROLE_ACTIVITI_USER&quot;</span>, <span class="string">&quot;GROUP_otherTeam&quot;</span>&#125;,</span><br><span class="line">                 &#123;<span class="string">&quot;system&quot;</span>, <span class="string">&quot;password&quot;</span>, <span class="string">&quot;ROLE_ACTIVITI_USER&quot;</span>&#125;,</span><br><span class="line">                 &#123;<span class="string">&quot;admin&quot;</span>, <span class="string">&quot;password&quot;</span>, <span class="string">&quot;ROLE_ACTIVITI_ADMIN&quot;</span>&#125;,</span><br><span class="line">         &#125;;</span><br><span class="line">​</span><br><span class="line">         <span class="keyword">for</span> (String[] user : usersGroupsAndRoles) &#123;</span><br><span class="line">             List&lt;String&gt; authoritiesStrings = Arrays.asList(Arrays.copyOfRange(user, <span class="number">2</span>, user.length));</span><br><span class="line">             logger.info(<span class="string">&quot;&gt; Registering new user: &quot;</span> + user[<span class="number">0</span>] + <span class="string">&quot; with the following Authorities[&quot;</span> + authoritiesStrings + <span class="string">&quot;]&quot;</span>);</span><br><span class="line">             inMemoryUserDetailsManager.createUser(<span class="keyword">new</span> User(user[<span class="number">0</span>], passwordEncoder().encode(user[<span class="number">1</span>]),</span><br><span class="line">                     authoritiesStrings.stream().map(s -&gt; <span class="keyword">new</span> SimpleGrantedAuthority(s)).collect(Collectors.toList())));</span><br><span class="line">         &#125;</span><br><span class="line">​</span><br><span class="line">         <span class="keyword">return</span> inMemoryUserDetailsManager;</span><br><span class="line">     &#125;</span><br><span class="line">     <span class="meta">@Bean</span></span><br><span class="line">     <span class="function"><span class="keyword">public</span> PasswordEncoder <span class="title">passwordEncoder</span><span class="params">()</span> </span>&#123;</span><br><span class="line">         <span class="keyword">return</span> <span class="keyword">new</span> BCryptPasswordEncoder();</span><br><span class="line">     &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="1-5-创建Bpmn文件"><a href="#1-5-创建Bpmn文件" class="headerlink" title="1.5 创建Bpmn文件"></a>1.5 创建Bpmn文件</h2><p>Activiti7可以自动部署流程，前提是在resources目录下，创建一个新的目录processes，用来放置bpmn文件。</p>
<p>创建一个简单的Bpmn流程文件，并设置任务的用户组Candidate Groups。</p>
<p>Candidate Groups中的内容与上面DemoApplicationConfiguration类中出现的用户组名称要保持一致，可以填写：activitiTeam 或者 otherTeam。</p>
<p>这样填写的好处：当不确定到底由谁来负责当前任务的时候，只要是Groups内的用户都可以拾取这个任务</p>
<img src="/2023/04/04/%E3%80%90Activiti7%E3%80%911%E3%80%81SpringBoot%E6%95%B4%E5%90%88Activiti7/bb6d77584b43f67fa97a7c4d09dce686.png" class="" title="This is an image">

<h2 id="1-6-使用Junit方式测试"><a href="#1-6-使用Junit方式测试" class="headerlink" title="1.6 使用Junit方式测试"></a>1.6 使用Junit方式测试</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.test;</span><br><span class="line">​</span><br><span class="line"><span class="keyword">import</span> com.itheima.utils.SecurityUtil;</span><br><span class="line"><span class="keyword">import</span> org.activiti.api.process.model.ProcessInstance;</span><br><span class="line"><span class="keyword">import</span> org.activiti.api.process.model.builders.ProcessPayloadBuilder;</span><br><span class="line"><span class="keyword">import</span> org.activiti.api.process.runtime.ProcessRuntime;</span><br><span class="line"><span class="keyword">import</span> org.activiti.api.runtime.shared.query.Page;</span><br><span class="line"><span class="keyword">import</span> org.activiti.api.runtime.shared.query.Pageable;</span><br><span class="line"><span class="keyword">import</span> org.activiti.api.task.model.Task;</span><br><span class="line"><span class="keyword">import</span> org.activiti.api.task.model.builders.TaskPayloadBuilder;</span><br><span class="line"><span class="keyword">import</span> org.activiti.api.task.runtime.TaskRuntime;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.repository.ProcessDefinition;</span><br><span class="line"><span class="keyword">import</span> org.junit.Test;</span><br><span class="line"><span class="keyword">import</span> org.junit.runner.RunWith;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.test.context.SpringBootTest;</span><br><span class="line"><span class="keyword">import</span> org.springframework.test.context.junit4.SpringRunner;</span><br><span class="line">​</span><br><span class="line"><span class="meta">@RunWith(SpringRunner.class)</span></span><br><span class="line"><span class="meta">@SpringBootTest</span></span><br><span class="line"> <span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Actviti7DemoApplicationTests</span> </span>&#123;</span><br><span class="line">     <span class="meta">@Autowired</span></span><br><span class="line">     <span class="keyword">private</span> ProcessRuntime processRuntime;</span><br><span class="line">     <span class="meta">@Autowired</span></span><br><span class="line">     <span class="keyword">private</span> TaskRuntime taskRuntime;</span><br><span class="line">     <span class="meta">@Autowired</span></span><br><span class="line">     <span class="keyword">private</span> SecurityUtil securityUtil;</span><br><span class="line">​</span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testActBoot</span><span class="params">()</span></span>&#123;</span><br><span class="line">        System.out.println(taskRuntime);</span><br><span class="line">    &#125;</span><br><span class="line">​</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 查看流程定义</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">contextLoads</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        securityUtil.logInAs(<span class="string">&quot;system&quot;</span>);</span><br><span class="line">        Page&lt;org.activiti.api.process.model.ProcessDefinition&gt; processDefinitionPage =</span><br><span class="line">                processRuntime.processDefinitions(Pageable.of(<span class="number">0</span>, <span class="number">10</span>));</span><br><span class="line">        System.out.println(<span class="string">&quot;可用的流程定义数量：&quot;</span> + processDefinitionPage.getTotalItems());</span><br><span class="line">        <span class="keyword">for</span> (org.activiti.api.process.model.ProcessDefinition pd : processDefinitionPage.getContent()) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;流程定义：&quot;</span> + pd);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">​</span><br><span class="line">​</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 启动流程实例</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testStartProcess</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        securityUtil.logInAs(<span class="string">&quot;system&quot;</span>);</span><br><span class="line">        ProcessInstance pi = processRuntime.start(ProcessPayloadBuilder.</span><br><span class="line">                start().</span><br><span class="line">                withProcessDefinitionKey(<span class="string">&quot;myProcess&quot;</span>).</span><br><span class="line">                build());</span><br><span class="line">        System.out.println(<span class="string">&quot;流程实例ID：&quot;</span> + pi.getId());</span><br><span class="line">    &#125;</span><br><span class="line">​</span><br><span class="line">​</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     **查询任务，并完成自己的任务</span></span><br><span class="line"><span class="comment">     **/</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testTask</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        securityUtil.logInAs(<span class="string">&quot;jack&quot;</span>);</span><br><span class="line">        Page&lt;Task&gt; taskPage=taskRuntime.tasks(Pageable.of(<span class="number">0</span>,<span class="number">10</span>));</span><br><span class="line">        <span class="keyword">if</span> (taskPage.getTotalItems()&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">for</span> (Task task:taskPage.getContent())&#123;</span><br><span class="line">                taskRuntime.claim(TaskPayloadBuilder.</span><br><span class="line">                        claim().</span><br><span class="line">                        withTaskId(task.getId()).build());</span><br><span class="line">                System.out.println(<span class="string">&quot;任务：&quot;</span>+task);</span><br><span class="line">                taskRuntime.complete(TaskPayloadBuilder.</span><br><span class="line">                        complete().</span><br><span class="line">                        withTaskId(task.getId()).build());</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        Page&lt;Task&gt; taskPage2=taskRuntime.tasks(Pageable.of*(<span class="number">0</span>,<span class="number">10</span>));</span><br><span class="line">        <span class="keyword">if</span> (taskPage2.getTotalItems()&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;任务：&quot;</span>+taskPage2.getContent());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>




      
    </div>
    <footer class="article-footer">
      <a data-url="https://xlh_blog.gitee.io/2023/04/04/%E3%80%90Activiti7%E3%80%911%E3%80%81SpringBoot%E6%95%B4%E5%90%88Activiti7/" data-id="clt2kwbi20001s337af2q6ot9" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2023/04/06/%E3%80%90Activiti7%E3%80%912%E3%80%81Activiti%E4%BB%BB%E5%8A%A1%E5%9B%9E%E9%80%80%EF%BC%8C%E8%B7%B3%E8%BD%AC/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          【Activiti7】2、Activiti任务回退，跳转
        
      </div>
    </a>
  
  
</nav>

  
</article>




</section>
        
          <aside id="sidebar">
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">分类</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/Activiti7/">Activiti7</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Git/">Git</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%85%B6%E4%BB%96/">其他</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%90%8E%E7%AB%AF/">后端</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E8%BF%90%E7%BB%B4/">运维</a></li></ul>
    </div>
  </div>


  
    

  
    
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">归档</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2023/04/">四月 2023</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">最新文章</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2023/04/10/%E3%80%90%E5%85%B6%E4%BB%96%E3%80%911%E3%80%81Mac%E9%83%A8%E7%BD%B2LskyPro%E6%90%AD%E5%BB%BA%E6%9C%AC%E5%9C%B0%E5%9B%BE%E5%BA%8A/">【其他】1、Mac部署LskyPro搭建本地图床</a>
          </li>
        
          <li>
            <a href="/2023/04/06/%E3%80%90%E8%BF%90%E7%BB%B4%E3%80%917%E3%80%81%E8%A7%A3%E5%86%B3virtualBox%E5%AF%BC%E5%85%A5voa%E6%96%87%E4%BB%B6%E5%90%8E%E6%97%A0%E6%B3%95%E4%B8%8A%E7%BD%91%E9%97%AE%E9%A2%98/">【运维】7、解决virtualBox导入voa文件后无法上网问题</a>
          </li>
        
          <li>
            <a href="/2023/04/06/%E3%80%90%E8%BF%90%E7%BB%B4%E3%80%916%E3%80%81Docker%E8%BF%90%E8%A1%8CSpringCloud%E5%BE%AE%E6%9C%8D%E5%8A%A1%E5%B9%B6%E9%80%9A%E8%BF%87IP%E8%BF%9B%E8%A1%8C%E6%9C%8D%E5%8A%A1%E6%B3%A8%E5%86%8C/">【运维】5、Docker运行SpringCloud微服务并通过IP进行服务注册</a>
          </li>
        
          <li>
            <a href="/2023/04/06/%E3%80%90%E8%BF%90%E7%BB%B4%E3%80%915%E3%80%81win10%E9%80%9A%E8%BF%87vagrant-virtulbox%E6%90%AD%E5%BB%BAcentos7%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%AF%E5%A2%83%E6%97%B6%E6%8A%A5%E9%94%99/">【运维】5、win10通过vagrant+virtulbox搭建centos7虚拟机环境时报错</a>
          </li>
        
          <li>
            <a href="/2023/04/06/%E3%80%90%E5%90%8E%E7%AB%AF%E3%80%91SpringBoot%E6%95%B4%E5%90%88MQTT%EF%BC%88EMQX%EF%BC%89/">【后端】SpringBoot整合MQTT（EMQX）</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2024 Mr.xi<br>
        <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
        <span id="busuanzi_container_site_pv">
          本文总阅读量<span id="busuanzi_value_page_pv"></span>次
        </span><a href="https://beian.miit.gov.cn/" target="_blank">京ICP备18049089号-2</a>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>


</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
    <a href="/about" class="mobile-nav-link">About</a>
  
</nav>
    

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>


  
<link rel="stylesheet" href="/fancybox/jquery.fancybox.css">

  
<script src="/fancybox/jquery.fancybox.pack.js"></script>




<script src="/js/script.js"></script>





<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?803c71743b7cfc4dac421ac4fc646963";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>



  </div>
</body>
</html>